var express = require("express");
var router = express.Router();

const { User, Course } = require("../../models");
// 复杂查询
const { Op } = require("sequelize");
// 自定义异常
const { NotFound } = require("http-errors");
// 自定义响应
const { success, failure } = require("../../utils/responses");
const { delKey } = require("../../utils/redis");

/**
 * 查询用户列表
 * GET /admin/users
 * @query { limit, offset }
 * @return 用户列表
 */
router.get("/", async function (req, res, next) {
  // 处理异常 try catch
  try {
    // 用户的分页查询
    const query = req.query;
    // 当前页码 默认 1
    const currentPage = Math.abs(+query.currentPage) || 1;
    // 每页多少条数据 默认 10
    const pageSize = Math.abs(+query.pageSize) || 10;
    // 偏移量
    const offset = (currentPage - 1) * pageSize;

    const condition = {
      where: {},
      order: [
        ["id", "DESC"],
        // ['createdAt', 'DESC']
      ],
      limit: pageSize,
      offset,
    };
    // 查询
    if (query.email) {
      condition.where.email = query.email;
    }

    if (query.username) {
      condition.where.username = query.username;
    }

    if (query.nickname) {
      condition.where.nickname = {
        [Op.like]: `%${query.nickname}%`,
      };
    }

    if (query.role) {
      condition.where.role = query.role;
    }
    // 查询所有用户
    const { rows, count } = await User.findAndCountAll(condition);
    // 成功状态码 默认200 正确响应了
    success(res, "查询用户列表成功", {
      users: rows,
      pagination: {
        currentPage,
        pageSize,
        total: count,
      },
    });
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 查询当前登录的用户详情
 * GET /admin/users/me
 */
router.get("/me", async function (req, res) {
  try {
    const user = req.user;
    success(res, "查询当前用户信息成功。", { user });
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 查询用户详情
 * GET /admin/users/:id
 * @params id 用户id
 * @return 用户详情
 */
router.get("/:id", async function (req, res, next) {
  // 处理异常 try catch
  try {
    const user = await getUser(req);
    // 成功状态码 默认200
    success(res, "查询用户详情成功", { user });
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 新增用户
 * POST /admin/users
 * @body title 标题
 * @body content 内容
 * @return
 */
router.post("/", async function (req, res, next) {
  // 处理异常 try catch
  try {
    const body = filterBody(req);
    const user = await User.create(body);
    // 成功状态码 201 正确响应了，并创建了新的资源
    success(res, "新增用户成功", user, 201);
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 更新用户
 * PUT /admin/users/:id
 * @params id 用户id
 * @body title 标题
 * @body content 内容
 * @return 用户详情
 */
router.put("/:id", async function (req, res, next) {
  // 处理异常 try catch
  try {
    const user = await getUser(req);
    // 白名单过滤
    const body = filterBody(req);

    await user.update(body);
    await clearCache(user);

    success(res, "更新用户成功", { user });
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 公共方法: 查询当前用户
 */
async function getUser(req) {
  // 获取用户ID
  const { id } = req.params;
  // 查询用户时， 查询关联课程列表
  const condition = {
    include: [
      {
        model: Course,
        as: "courses",
      },
    ],
  };

  // 查询用户
  const user = await User.findByPk(id, condition);
  // 用户不存在 抛出异常
  if (!user) {
    throw new NotFound(`ID: ${id}的用户不存在`);
  }
  // 用户存在
  return user;
}

/**
 * 白名单过滤
 * @param req
 * @returns {{password, role: (number|string|*), introduce: ({type: *}|*),
 *           sex: ({allowNull: boolean, type: *, validate: {notNull: {msg: string},
 *           notEmpty: {msg: string},
 *           isIn: {args: [number[]], msg: string}}}|{defaultValue: number, allowNull: boolean, type: *}|*),
 *           nickname: (string|*), company: ({type: *}|*),
 *           avatar: ({type: *, validate: {isUrl: {msg: string}}}|*), email: (string|*), username
 *          }}
 */
function filterBody(req) {
  // 只保留白名单字段
  return {
    email: req.body.email,
    username: req.body.username,
    password: req.body.password,
    nickname: req.body.nickname,
    sex: req.body.sex,
    company: req.body.company,
    introduce: req.body.introduce,
    role: req.body.role,
    avatar: req.body.avatar,
  };
}

/**
 * 清除缓存
 * @param user
 * @returns {Promise<void>}
 */
async function clearCache(user) {
  await delKey(`user:${user.id}`);
}

module.exports = router;
